package com.zy.nft_system.websocket;

import com.alibaba.fastjson.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * @author 这是那头猪？
 * @version 1.0
 * @description: TODO
 * @date 2022/12/19 14:02
 */

@Slf4j
@Component
@ServerEndpoint("/customerService/{userId}/{userName}")
public class MyWebSocketServer {

    /**
     * 在线人数
     */
    public static int onlineNumber = 0;

    /**
     * 会话
     */
    private Session session;


    /**
     * 用户名
     */
    private String userName;

    /**
     * 以用户名为key，MyWebSocketServer为对象保存起来
     */
    private static Map<String, MyWebSocketServer> clients = new ConcurrentHashMap<>();



    /**
     * 建立连接
     */
    @OnOpen
    public void onOpen(@PathParam(value = "userName") String userName, Session session) throws IOException {
        this.onlineNumber++;
        this.session=session;
        this.userName=userName;
        clients.put(userName, this);
        log.info("用户{}上线当前在线人数为{}", userName, onlineNumber);
        //将用户信息返回给前端
        //有点像hashmap 不过是json格式的
        JSONObject result = new JSONObject();
        //有点像list
        JSONArray array = new JSONArray();
        result.set("users", array);
        for (String key : clients.keySet()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("userName", clients.get(key).userName);
            // {"userName": "zhang"}
            array.add(jsonObject);
        }
        //{"users": [{"userName": "zhang"},{ "userName": "admin"}]}
        sendMessageAll(JSON.toJSONString(result));
    }

    @OnError
    public void onError(Throwable error) {
        log.info("服务端发生了错误" + error.getMessage());
    }
    /**
     * 连接关闭
     */
    @OnClose
    public synchronized void onClose(@PathParam(value = "userName") String userName) {
        onlineNumber--;
        clients.remove(userName);
        log.info("用户{}下线当前在线人数为{}", userName, onlineNumber);
    }

    /**
     * 收到客户端的消息
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("userName") String userName) throws IOException {
        JSONObject obj = JSONUtil.parseObj(message);
        String fromImg = (String) obj.get("fromImg");
        String to = (String) obj.get("to");
        String text = (String) obj.get("text");
        //{from: 'ww', fromImg: '/User-Img/eee61b33-0365-4467-844e-42f152693afe.jpg', to: 'qq', text: '咕咕iuo'}
        log.info("接受到用户{}-发给用户{}-的消息-{}", userName, to, text);

        // 根据 to用户名来获取 session，再通过session发送消息文本
        Session toSession = clients.get(to).session;
        if (toSession != null) {
            // 服务器端 再把消息组装一下，组装后的消息包含发送人和发送的文本内容
            // {from: 'ww',  fromImg: '/User-Img/eee61b33-0365-4467-844e-42f152693afe.jpg', "text": '咕咕iuo'}
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("from", userName);  // from 是 ww
            jsonObject.set("fromImg", fromImg);
            jsonObject.set("text", text);  // text 同上面的text
            this.sendMessageTo(jsonObject.toString(), to);
            log.info("发送给用户username={}，消息：{}", to, jsonObject.toString());
        } else {
            log.info("发送失败，未找到用户username={}的session", to);
        }
    }

    // 发消息给某个用户
    public void sendMessageTo(String message, String toUserName) throws IOException {
        for (String userName : MyWebSocketServer.clients.keySet()) {
            if (userName.equals(toUserName)) {
                MyWebSocketServer.clients.get(userName).session.getAsyncRemote().sendText(message);
                log.info("消息发送成功");
                break;
            }
        }
    }
    //发送消息给全部用户
    public void sendMessageAll(String message) throws IOException {
        for (String userName : MyWebSocketServer.clients.keySet()) {
                MyWebSocketServer.clients.get(userName).session.getAsyncRemote().sendText(message);
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineNumber;
    }

}
